home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
- The Netherlands.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
-
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- ******************************************************************/
-
- /* Python interpreter main program */
-
- #include "Python.h"
- #include "pythonresources.h"
- #include "import.h"
- #include "marshal.h"
- #include "macglue.h"
-
- #include <Memory.h>
- #include <Resources.h>
- #include <stdio.h>
- #include <Events.h>
- #include <Windows.h>
- #include <Desk.h>
- #include <Fonts.h>
-
- #ifdef __MWERKS__
- #include <SIOUX.h>
- #define USE_SIOUX
- #endif
-
- #ifdef THINK_C
- #include <console.h>
- #endif
-
- #define STARTUP "PythonStartup"
-
- extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */
- extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */
- extern int Py_SuppressPrintingFlag; /* For ceval.c, declared in pythonrun.c */
- short PyMac_AppRefNum; /* RefNum of application resource fork */
-
-
- /* Subroutines that live in their own file */
- extern char *Py_GetVersion Py_PROTO((void));
- extern char *Py_GetCopyright Py_PROTO((void));
-
-
- /* For Py_GetArgcArgv(); set by main() */
- static char **orig_argv;
- static int orig_argc;
-
- PyMac_PrefRecord options;
-
- static void Py_Main Py_PROTO((int, char **)); /* Forward */
- void PyMac_Exit Py_PROTO((int)); /* Forward */
-
- /* Initialize the Mac toolbox world */
-
- static void
- init_mac_world()
- {
- #ifdef THINK_C
- printf("\n");
- #else
- MaxApplZone();
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- TEInit();
- InitDialogs((long)0);
- InitMenus();
- InitCursor();
- #endif
- }
-
- /*
- ** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
- */
- static void
- PyMac_InteractiveOptions(PyMac_PrefRecord *p, int *argcp, char ***argvp)
- {
- KeyMap rmap;
- unsigned char *map;
- short item, type;
- ControlHandle handle;
- DialogPtr dialog;
- Rect rect;
- int old_argc = *argcp;
- int i;
-
- /*
- ** If the preferences disallows interactive options we return,
- ** similarly of <option> isn't pressed.
- */
- if (p->nointopt) return;
-
- GetKeys(rmap);
- map = (unsigned char *)rmap;
- if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
- return;
-
- dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
- if ( dialog == NULL ) {
- printf("Option dialog not found - cannot set options\n");
- return;
- }
- SetDialogDefaultItem(dialog, OPT_OK);
- SetDialogCancelItem(dialog, OPT_CANCEL);
-
- /* Set default values */
- #define SET_OPT_ITEM(num, var) \
- GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
- SetCtlValue(handle, (short)p->var);
-
- SET_OPT_ITEM(OPT_INSPECT, inspect);
- SET_OPT_ITEM(OPT_VERBOSE, verbose);
- SET_OPT_ITEM(OPT_SUPPRESS, suppress_print);
- SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
- SET_OPT_ITEM(OPT_DEBUGGING, debugging);
- SET_OPT_ITEM(OPT_KEEPNORMAL, keep_normal);
- SET_OPT_ITEM(OPT_KEEPERROR, keep_error);
- /* The rest are not settable interactively */
-
- #undef SET_OPT_ITEM
-
- while (1) {
- handle = NULL;
- ModalDialog(NULL, &item);
- if ( item == OPT_OK )
- break;
- if ( item == OPT_CANCEL ) {
- DisposDialog(dialog);
- exit(0);
- }
- if ( item == OPT_CMDLINE ) {
- int new_argc, newer_argc;
- char **new_argv, **newer_argv;
-
- new_argc = ccommand(&new_argv);
- newer_argc = (new_argc-1) + old_argc;
- newer_argv = malloc((newer_argc+1)*sizeof(char *));
- if( !newer_argv )
- Py_FatalError("Cannot malloc argv\n");
- for(i=0; i<old_argc; i++)
- newer_argv[i] = (*argvp)[i];
- for(i=old_argc; i<=newer_argc; i++) /* Copy the NULL too */
- newer_argv[i] = new_argv[i-old_argc+1];
- *argvp = newer_argv;
- *argcp = newer_argc;
-
- /* XXXX Is it not safe to use free() here, apparently */
- }
- #define OPT_ITEM(num, var) \
- if ( item == (num) ) { \
- p->var = !p->var; \
- GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
- SetCtlValue(handle, (short)p->var); \
- }
-
- OPT_ITEM(OPT_INSPECT, inspect);
- OPT_ITEM(OPT_VERBOSE, verbose);
- OPT_ITEM(OPT_SUPPRESS, suppress_print);
- OPT_ITEM(OPT_UNBUFFERED, unbuffered);
- OPT_ITEM(OPT_DEBUGGING, debugging);
- OPT_ITEM(OPT_KEEPNORMAL, keep_normal);
- OPT_ITEM(OPT_KEEPERROR, keep_error);
-
- #undef OPT_ITEM
- }
- DisposDialog(dialog);
- }
-
- /*
- ** Initialization code, shared by interpreter and applets
- */
- static void
- init_common(int *argcp, char ***argvp)
- {
- /* Remember resource fork refnum, for later */
- PyMac_AppRefNum = CurResFile();
-
- /* Initialize toolboxes */
- init_mac_world();
-
- #ifdef USE_MAC_SHARED_LIBRARY
- /* Add the shared library to the stack of resource files */
- PyMac_AddLibResources();
- #endif
-
- #if defined(USE_GUSI)
- /* Setup GUSI */
- GUSIDefaultSetup();
- PyMac_SetGUSISpin();
- PyMac_SetGUSIOptions();
- #endif
-
- #ifdef USE_SIOUX
- /* Set various SIOUX flags. Some are changed later based on options */
- SIOUXSettings.asktosaveonclose = 0;
- SIOUXSettings.showstatusline = 0;
- SIOUXSettings.tabspaces = 4;
- #endif
-
- /* Get options from preference file (or from applet resource fork) */
- options.keep_error = 1; /* default-default */
- PyMac_PreferenceOptions(&options);
-
- /* Create argc/argv. Do it before we go into the options event loop. */
- *argcp = PyMac_GetArgv(argvp, options.noargs);
-
- /* Do interactive option setting, if allowed and <option> depressed */
- PyMac_InteractiveOptions(&options, argcp, argvp);
-
- /* Copy selected options to where the machine-independent stuff wants it */
- Py_VerboseFlag = options.verbose;
- Py_SuppressPrintingFlag = options.suppress_print;
- Py_DebugFlag = options.debugging;
- if ( options.noargs )
- PyMac_DoYieldEnabled = 0;
-
- /* Set buffering */
- if (options.unbuffered) {
- #ifndef MPW
- setbuf(stdout, (char *)NULL);
- setbuf(stderr, (char *)NULL);
- #else
- /* On MPW (3.2) unbuffered seems to hang */
- setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
- setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
- #endif
- }
- }
-
- /*
- ** Inspection mode after script/applet termination
- */
- static int
- run_inspect()
- {
- int sts = 0;
-
- if (options.inspect && isatty((int)fileno(stdin)))
- sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
- return sts;
- }
-
- #ifdef USE_MAC_APPLET_SUPPORT
- /* Applet support */
-
- /* Run a compiled Python Python script from 'PYC ' resource __main__ */
- static int
- run_main_resource()
- {
- Handle h;
- long size;
- PyObject *code;
- PyObject *result;
-
- h = GetNamedResource('PYC ', "\p__main__");
- if (h == NULL) {
- Alert(NOPYC_ALERT, NULL);
- return 1;
- }
- size = GetResourceSizeOnDisk(h);
- HLock(h);
- code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
- HUnlock(h);
- ReleaseResource(h);
- if (code == NULL) {
- PyErr_Print();
- return 1;
- }
- result = PyImport_ExecCodeModule("__main__", code);
- Py_DECREF(code);
- if (result == NULL) {
- PyErr_Print();
- return 1;
- }
- Py_DECREF(result);
- return 0;
- }
-
- /* Initialization sequence for applets */
- void
- PyMac_InitApplet()
- {
- int argc;
- char **argv;
- int err;
-
- init_common(&argc, &argv);
-
- Py_Initialize();
- PySys_SetArgv(argc, argv);
-
- err = run_main_resource();
-
- err = (run_inspect() || err);
-
- fflush(stderr);
- fflush(stdout);
- PyMac_Exit(err);
- /* XXX Should we bother to Py_Exit(sts)? */
- }
-
- #endif /* USE_MAC_APPLET_SUPPORT */
-
- /* For normal application */
- void
- PyMac_InitApplication()
- {
- int argc;
- char **argv;
-
- init_common(&argc, &argv);
-
- if ( argc > 1 ) {
- /* We're running a script. Attempt to change current directory */
- char curwd[256], *endp;
-
- strcpy(curwd, argv[1]);
- endp = strrchr(curwd, ':');
- if ( endp && endp > curwd ) {
- *endp = '\0';
-
- chdir(curwd);
- #ifdef USE_GUSI
- /* Change MacOS's idea of wd too */
- PyMac_FixGUSIcd();
- #endif
- }
- }
- Py_Main(argc, argv);
- }
-
- /* Main program */
-
- static void
- Py_Main(argc, argv)
- int argc;
- char **argv;
- {
- int sts;
- char *command = NULL;
- char *filename = NULL;
- FILE *fp = stdin;
-
- orig_argc = argc; /* For Py_GetArgcArgv() */
- orig_argv = argv;
- filename = argv[1];
-
- if (Py_VerboseFlag ||
- command == NULL && filename == NULL && isatty((int)fileno(fp)))
- fprintf(stderr, "Python %s\n%s\n",
- Py_GetVersion(), Py_GetCopyright());
-
- if (filename != NULL) {
- if ((fp = fopen(filename, "r")) == NULL) {
- fprintf(stderr, "%s: can't open file '%s'\n",
- argv[0], filename);
- PyMac_Exit(2);
- }
- }
-
- /* We initialize the menubar here, hoping SIOUX is initialized by now */
- PyMac_InitMenuBar();
-
- Py_Initialize();
-
- PySys_SetArgv(argc-1, argv+1);
-
- if (filename == NULL && isatty((int)fileno(fp))) {
- FILE *fp = fopen(STARTUP, "r");
- if (fp != NULL) {
- (void) PyRun_SimpleFile(fp, STARTUP);
- PyErr_Clear();
- fclose(fp);
- }
- }
- sts = PyRun_AnyFile(
- fp, filename == NULL ? "<stdin>" : filename) != 0;
- if (filename != NULL)
- fclose(fp);
-
- if ( filename != NULL || command != NULL )
- sts = (run_inspect() || sts);
-
- Py_Exit(sts);
- /*NOTREACHED*/
- }
-
- /*
- ** Terminate application
- */
- void
- PyMac_Exit(status)
- int status;
- {
- int keep;
-
- if ( status )
- keep = options.keep_error;
- else
- keep = options.keep_normal;
-
- #ifdef USE_SIOUX
- if (keep) {
- SIOUXSettings.standalone = 1;
- SIOUXSettings.autocloseonquit = 0;
- SIOUXSetTitle("\p\307terminated\310");
- }
- else
- SIOUXSettings.autocloseonquit = 1;
- #ifdef USE_GUSI
- /*
- ** Workaround for Sioux/GUSI combo: we should not call
- ** SiouxHandleOneEvent after the window is closed
- */
- PyMac_ConsoleIsDead = 1;
- #endif /* USE_GUSI */
- #endif /* USE_SIOUX */
- #ifdef THINK_C
- console_options.pause_atexit = keep;
- #endif
-
- exit(status);
- }
-
- /* Return the program name -- some code out there needs this. */
-
- char *
- Py_GetProgramName()
- {
- return orig_argv[0];
- }
-
-
- /* Make the *original* argc/argv available to other modules.
- This is rare, but it is needed by the secureware extension. */
-
- void
- Py_GetArgcArgv(argc,argv)
- int *argc;
- char ***argv;
- {
- *argc = orig_argc;
- *argv = orig_argv;
- }
-
- /* More cruft that shouldn't really be here, used in sysmodule.c */
-
- char *
- Py_GetPrefix()
- {
- return "";
- }
-
- char *
- Py_GetExecPrefix()
- {
- return "";
- }
-